﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;

public class BitReader
{
	public int curPos;
	public TextAsset textAsset;
	public byte[] pBuffer;
	public uint m_uFileSize;
	public uint GetFileSize( ) { return m_uFileSize; }
	
	public byte getByte() { return pBuffer[curPos++];}
	public int readInt() { int aT = getByte() & 0xff; int bT = getByte()&0xff; int cT = getByte()&0xff; int dT = getByte()&0xff; return (aT|(bT<<8)|(cT<<16)|(dT<<24)); }
	public uint readUInt() { uint aT = (uint)(getByte() & 0xff); uint bT = (uint)(getByte()&0xff); uint cT = (uint)(getByte()&0xff); uint dT = (uint)(getByte()&0xff); return (aT|(bT<<8)|(cT<<16)|(dT<<24)); }
	public void readByte(byte[] dest, uint nPos, int length)
	{
		for(int i = 0; i < length; i++)
		{
			dest[i] = pBuffer[nPos+i];
		}
	}
	public uint DecryptInt( uint uValue )
	{
		uint uRet1 = (uValue & 0x000000FF) << 24;
		uint uRet2 = (uValue & 0x0000FF00) << 8;
		uint uRet3 = (uValue & 0x00FF0000) >> 8;
		uint uRet4 = (uValue & 0xFF000000) >> 24;
		return uRet1 | uRet2 | uRet3 | uRet4;
	}
	public void ReadFile(string file){
		textAsset = Resources.Load(file) as TextAsset;
		pBuffer = textAsset.bytes;
		m_uFileSize = (uint)pBuffer.Length;
		curPos = 0;
	}
}
public class DBCReader {
	private byte[][] m_pRecordList;
	private int[] m_FieldOffset;
	private byte[] m_pStringTable;
	private uint m_uRecordSize;
	private uint m_uRecordCount;
	private uint m_uFieldCount;
	private uint m_uActualDataOffset;
	public uint GetRecordSize( ) { return m_uRecordSize;	}
	public uint GetRecordCount( ) { return m_uRecordCount; }
	public uint GetFieldCount( ) { return m_uFieldCount; }
	// Use this for initialization

	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
		
	}
	enum DataType
	{
		DT_Int = 1,
		DT_Float = 2,
		DT_String = 3,
	};
	public bool ReadFile(string file){
		BitReader bitReader = new BitReader();
		bitReader.ReadFile(file);

		if( bitReader.getByte() != 'B' || bitReader.getByte() != 'A' || bitReader.getByte() != 'D' || bitReader.getByte() != 'X')
		{
			return false;
		}

		//uint uVersion =
		bitReader.readUInt();

		m_uRecordCount = bitReader.readUInt();
		m_uRecordCount = bitReader.DecryptInt( m_uRecordCount );

		m_uRecordSize = bitReader.readUInt();
		m_uRecordSize = bitReader.DecryptInt( m_uRecordSize );

		m_uFieldCount = bitReader.readUInt();
		m_uFieldCount = bitReader.DecryptInt( m_uFieldCount );

		m_uActualDataOffset = bitReader.readUInt();
		m_uActualDataOffset = bitReader.DecryptInt( m_uActualDataOffset );

		uint uStringOffset = bitReader.readUInt();
		uStringOffset = bitReader.DecryptInt( uStringOffset );
		m_pStringTable = new byte[bitReader.GetFileSize( )-uStringOffset];
		bitReader.readByte(m_pStringTable, uStringOffset, m_pStringTable.Length);

		//uint uCapOffset = 
		bitReader.readUInt();

		m_FieldOffset = new int[m_uFieldCount];
		for(int i = 0; i < m_uFieldCount; i++)
		{
			m_FieldOffset[i] = bitReader.readInt();
		}

		// 设置字符串的地址
		m_pRecordList = new byte[m_uRecordCount][];
		for( uint i = 0; i < m_uRecordCount; ++i )
		{
			m_pRecordList[i] = new byte[m_uRecordSize];
			bitReader.readByte(m_pRecordList[i], (m_uActualDataOffset+m_uRecordSize*i), (int)m_uRecordSize);
		}
		return true;
	}
	public int GetInt( uint nID, uint uField ) 
	{
		int nPos = m_FieldOffset[uField];
		if(nPos == (int)DataType.DT_String)
		{
			int aT = m_pRecordList[nID][uField*4] & 0xff; 
			int bT = m_pRecordList[nID][uField*4+1]&0xff; 
			int cT = m_pRecordList[nID][uField*4+2]&0xff; 
			int dT = m_pRecordList[nID][uField*4+3]&0xff; 
			nPos = (aT|(bT<<8)|(cT<<16)|(dT<<24));
			return nPos;
		}
		byte[] temp = {0,0,0,0}; 
		temp[0] = m_pRecordList[nID][uField*4]; 
		temp[1] = m_pRecordList[nID][uField*4+1]; 
		temp[2] = m_pRecordList[nID][uField*4+2]; 
		temp[3] = m_pRecordList[nID][uField*4+3]; 
		return BitConverter.ToInt32(temp, 0);
	}
	public bool GetBool( uint nID, uint uField )
	{ 
		return m_pRecordList[nID][uField*4]!=0;
	}
	public char GetChar( uint nID, uint uField ) 
	{ 
		return (char)m_pRecordList[nID][uField*4];
	}
	public short GetShort( uint nID, uint uField ) 
	{
		byte[] temp = {0,0}; 
		temp[0] = m_pRecordList[nID][uField*4]; 
		temp[1] = m_pRecordList[nID][uField*4+1]; 
		return BitConverter.ToInt16(temp, 0);
	}
	public float GetFloat( uint nID, uint uField ) 
	{
		byte[] temp = {0,0,0,0}; 
		temp[0] = m_pRecordList[nID][uField*4]; 
		temp[1] = m_pRecordList[nID][uField*4+1]; 
		temp[2] = m_pRecordList[nID][uField*4+2]; 
		temp[3] = m_pRecordList[nID][uField*4+3]; 
		return BitConverter.ToSingle(temp, 0);
	}
	public string GetString( uint nID, uint uField ) 
	{
		int uStringOffset = GetInt( nID, uField );
		int length = 0;
		for(int i = uStringOffset; i < m_pStringTable.Length; i++)
		{
			if(m_pStringTable[i] == 0)
			{
				break;
			}
			length++;
		}
		return System.Text.Encoding.ASCII.GetString(m_pStringTable, uStringOffset, length);
	}
}
